package com.googlecode.pwlodars.piteststat.tests;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.hamcrest.BaseMatcher;

import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

/**
 * 
 * @author Pawel Wlodarski (pawel.wlodarski@tomtom.com)
 * 
 */
public abstract class SmartBaseMatcher<T> extends BaseMatcher<T> {

    private final Class<T> genericType;

    @SuppressWarnings("unchecked")
    public SmartBaseMatcher() {
        final Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

        if (type instanceof ParameterizedTypeImpl) {
            final ParameterizedTypeImpl typeImpl = (ParameterizedTypeImpl) type;
            this.genericType = (Class<T>) typeImpl.getRawType();
        } else {
            this.genericType = (Class<T>) type;
        }

    }

    abstract public boolean performConditionChecking(final T objectInTestContext) throws Exception;

    public boolean matches(final Object obj) {
        try {
            return performConditionChecking(genericType.cast(obj));
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }

}